/*
 * FreeModbus Libary: MSP430 Port
 * Copyright (C) 2006 Christian Walter <wolti@sil.at>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * File: $Id$
 */

/* ----------------------- Platform includes --------------------------------*/
#include "port.h"

/* ----------------------- Modbus includes ----------------------------------*/
#include "mb.h"
#include "mbport.h"
#include "USART.h"
#include "system.h"
/* ----------------------- Defines ------------------------------------------*/
#define U0_CHAR                 ( 0x10 )        /* Data 0:7-bits / 1:8-bits */

#define DEBUG_PERFORMANCE       ( 1 )

#if DEBUG_PERFORMANCE == 1
#define DEBUG_PIN_RX            ( 0 )
#define DEBUG_PIN_TX            ( 1 )
#define DEBUG_PORT_DIR          ( P1DIR )
#define DEBUG_PORT_OUT          ( P1OUT )
#define DEBUG_INIT( )           \
  do \
  { \
    DEBUG_PORT_DIR |= ( 1 << DEBUG_PIN_RX ) | ( 1 << DEBUG_PIN_TX ); \
    DEBUG_PORT_OUT &= ~( ( 1 << DEBUG_PIN_RX ) | ( 1 << DEBUG_PIN_TX ) ); \
  } while( 0 ); 
#define DEBUG_TOGGLE_RX( ) DEBUG_PORT_OUT ^= ( 1 << DEBUG_PIN_RX )
#define DEBUG_TOGGLE_TX( ) DEBUG_PORT_OUT ^= ( 1 << DEBUG_PIN_TX )

#else

#define DEBUG_INIT( )
#define DEBUG_TOGGLE_RX( )
#define DEBUG_TOGGLE_TX( )
#endif

/* ----------------------- Static variables ---------------------------------*/
UCHAR           ucGIEWasEnabled = FALSE;
UCHAR           ucCriticalNesting = 0x00;

/* ----------------------- Start implementation -----------------------------*/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    ENTER_CRITICAL_SECTION(  );
    if( xRxEnable ){
        //使能串口接收
        USART1 -> CR1 |= (1<<2);
        // EXIT_CRITICAL_SECTION(  );     
        // DelayMs(2);  /*进入发送完成中断以后，还要延时2-4ms等待串口数据完全发送出去才使能接收，不然会导致最后一个字节发送不完*/
        // ENTER_CRITICAL_SECTION(  );        
        //使能串口接收中断
        __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);       
    }else{
        //失能串口接收
        USART1 -> CR1 &=~ (1<<2);     
    }

    if( xTxEnable ){
        //使能串口发送
        USART1 -> CR1 |= (1<<3);
        //使能发送中断(TXE)
        __HAL_UART_ENABLE_IT(&huart1,UART_IT_TXE);
    }else{
        //失能串口发送
        USART1 -> CR1 &=~ (1<<3);
        //失能串口发送中断
        __HAL_UART_DISABLE_IT(&huart1,UART_IT_TXE);                
    }
    EXIT_CRITICAL_SECTION(  );
}

BOOL
xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
    MX_USART1_UART_Init();
    return TRUE;
}

BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
    //发送一个字节
    USART1 -> TDR = ucByte;
    //使能发送中断(TXE)
    __HAL_UART_ENABLE_IT(&huart1,UART_IT_TXE);
    return TRUE;
}

BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
    //接收数据
    *pucByte = USART1 -> RDR;
    //使能接收
    USART1 -> CR1 |= (1<<2);
    return TRUE;
}

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  //HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  if( __HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != 0)
  {
    pxMBFrameCBByteReceived(  );
  }
  else if( __HAL_UART_GET_FLAG(&huart1,UART_FLAG_TXE) != 0 )
  {
    pxMBFrameCBTransmitterEmpty(  );
  }

  if( __HAL_UART_GET_FLAG(&huart1,UART_FLAG_ORE) )
  {
    __HAL_UART_CLEAR_FLAG(&huart1,UART_CLEAR_OREF);
  }

  /* USER CODE END USART1_IRQn 1 */
}
